# -*- coding: utf-8 -*-
"""
数据服务模块 - 序列化器定义

本文件定义了数据服务模块中所有模型的序列化器，用于API数据的序列化和反序列化，包括：

1. DataSourceSerializer - 数据源序列化器
   - 序列化数据源的基本信息
   - 支持数据源的创建和更新
   - 自动处理时间戳字段

2. DataSyncTaskSerializer - 数据同步任务序列化器
   - 序列化同步任务的配置信息
   - 包含关联数据源的名称显示
   - 支持任务的创建和状态更新

3. DataSyncLogSerializer - 数据同步日志序列化器
   - 序列化同步任务的执行日志
   - 包含关联任务的名称显示
   - 提供详细的执行结果信息

4. FundDataSerializer - 基金数据序列化器
   - 序列化基金的基本信息
   - 提供基金类型的中文显示转换
   - 支持基金数据的查询和展示

5. FundDataDetailSerializer - 基金详情序列化器
   - 继承基金数据序列化器
   - 包含关联的净值数据
   - 提供最新净值的快速访问

6. FundNetValueSerializer - 基金净值序列化器
   - 序列化基金的净值数据
   - 包含关联基金的基本信息
   - 支持净值的时间序列查询

7. MarketDataSerializer - 市场数据序列化器
   - 序列化各种市场指标数据
   - 支持市场数据的查询和分析

8. DataSyncCreateSerializer - 数据同步创建序列化器
   - 用于创建数据同步任务的输入验证
   - 支持多种同步类型选择
   - 包含数据源有效性验证

9. FundSearchSerializer - 基金搜索序列化器
   - 用于基金搜索的参数验证
   - 支持多维度搜索条件
   - 包含风险等级和收益率范围过滤

所有序列化器都基于Django REST Framework实现，
提供完整的数据验证、转换和格式化功能。

Author: zhaozeliang
Date: 2025-09-06
"""

from rest_framework import serializers  # type: ignore
from .models import DataSource, DataSyncTask, DataSyncLog, FundInfo, FundInfoDetail, FundNavDetail, MarketData, FinalFundScraper


class DataSourceSerializer(serializers.ModelSerializer):
    """数据源序列化器"""
    
    class Meta:
        model = DataSource
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')


class DataSyncTaskSerializer(serializers.ModelSerializer):
    """数据同步任务序列化器"""
    data_source_name = serializers.CharField(source='data_source.name', read_only=True)
    
    class Meta:
        model = DataSyncTask
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')


class DataSyncLogSerializer(serializers.ModelSerializer):
    """数据同步日志序列化器"""
    task_name = serializers.CharField(source='task.name', read_only=True)
    
    class Meta:
        model = DataSyncLog
        fields = '__all__'
        read_only_fields = ('created_at',)


class FundInfoSerializer(serializers.ModelSerializer):
    """基金数据序列化器"""
    fund_type_display = serializers.SerializerMethodField()
    
    class Meta:
        model = FundInfo
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')
    
    def get_fund_type_display(self, obj):
        """将英文基金类型代码转换为中文显示"""
        type_mapping = {
            'stock': '股票型',
            'bond': '债券型',
            'hybrid': '混合型',
            'money': '货币型',
            'index': '指数型',
            'qdii': 'QDII',
            'fof': 'FOF',
            'other': '其他'
        }
        return type_mapping.get(obj.fund_type, obj.fund_type or '未知')


class FinalFundScraperSerializer(serializers.ModelSerializer):
    """基金净值数据序列化器（final_fund_scraper表）"""
    
    # 为了与前端字段名保持一致，重新映射字段名
    nav = serializers.DecimalField(source='unit_nav', max_digits=10, decimal_places=4, read_only=True)
    
    class Meta:
        model = FinalFundScraper
        fields = ['fund_code', 'fund_name', 'nav_date', 'nav', 'cumulative_nav', 'daily_growth_rate']
        read_only_fields = ('created_at', 'update_date')


class MarketDataSerializer(serializers.ModelSerializer):
    """市场数据序列化器"""
    
    class Meta:
        model = MarketData
        fields = '__all__'
        read_only_fields = ('created_at',)


class FundInfoDetailSerializer(serializers.ModelSerializer):
    """基金数据详情序列化器"""
    latest_net_value = serializers.SerializerMethodField()
    
    class Meta:
        model = FundInfo
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')
    
    def get_latest_net_value(self, obj):
        """获取最新净值"""
        from django.db import connection
        
        with connection.cursor() as cursor:
            cursor.execute("""
                SELECT unit_nav, accumulated_nav, nav_date, daily_growth_rate
                FROM fund_nav_detail_new 
                WHERE fund_code = %s 
                ORDER BY nav_date DESC 
                LIMIT 1
            """, [obj.fund_code])
            
            row = cursor.fetchone()
            if row:
                return {
                    'net_value': row[0],
                    'accumulated_value': row[1],
                    'value_date': row[2],
                    'daily_return': row[3]
                }
        return None


class FundInfoDetailTableSerializer(serializers.ModelSerializer):
    """基金详情表序列化器 - 用于fund_info_detail表"""
    
    class Meta:
        model = FundInfoDetail
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')


class DataSyncCreateSerializer(serializers.Serializer):
    """数据同步创建序列化器"""
    data_source_id = serializers.IntegerField()
    sync_type = serializers.ChoiceField(choices=[
        ('fund', '基金数据'),
        ('market', '市场数据'),
        ('all', '全部数据')
    ])
    
    def validate_data_source_id(self, value):
        """验证数据源ID"""
        try:
            DataSource.objects.get(id=value, is_active=True)
        except DataSource.DoesNotExist:
            raise serializers.ValidationError("数据源不存在或未激活")
        return value


class FundSearchSerializer(serializers.Serializer):
    """基金搜索序列化器"""
    keyword = serializers.CharField(max_length=100, required=False)
    fund_type = serializers.CharField(max_length=50, required=False)
    fund_company = serializers.CharField(max_length=100, required=False)
    risk_level = serializers.ChoiceField(
        choices=[(1, '低风险'), (2, '中低风险'), (3, '中风险'), (4, '中高风险'), (5, '高风险')],
        required=False
    )
    min_return = serializers.DecimalField(max_digits=10, decimal_places=4, required=False)
    max_return = serializers.DecimalField(max_digits=10, decimal_places=4, required=False)
    
    def validate(self, data):
        """验证搜索参数"""
        min_return = data.get('min_return')
        max_return = data.get('max_return')
        
        if min_return and max_return and min_return > max_return:
            raise serializers.ValidationError("最小收益率不能大于最大收益率")
        
        return data


class FundNavDetailSerializer(serializers.ModelSerializer):
    """基金历史净值明细序列化器"""
    fund_name = serializers.SerializerMethodField()
    
    class Meta:
        model = FundNavDetail
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')
    
    def get_fund_name(self, obj):
        """获取基金名称"""
        try:
            fund_info = FundInfo.objects.filter(fund_code=obj.fund_code).first()
            return fund_info.fund_name if fund_info else obj.fund_code
        except:
            return obj.fund_code